package com.nanyang.tms.manager.saleproduct.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.nanyang.common.core.annotation.SystemLog;
import com.nanyang.common.core.dict.CommonEnum;
import com.nanyang.common.core.page.PageBean;
import com.nanyang.common.core.page.PageTableBean;
import com.nanyang.common.tool.utils.convert.BeanUtils;
import com.nanyang.common.tool.utils.uuid.GlobalIdGeneratorUtil;
import com.nanyang.tms.common.contstant.TmsSerializeConstant;
import com.nanyang.tms.common.dict.TmsCommonEnum;
import com.nanyang.tms.common.dict.TmsExceptionEnum;
import com.nanyang.tms.common.exception.TmsManagerException;
import com.nanyang.tms.common.util.TmsExceptionUtil;
import com.nanyang.tms.dao.saleproduct.SaleProductCarryRuleDao;
import com.nanyang.tms.dao.saleproduct.SaleProductDao;
import com.nanyang.tms.dao.saleproduct.SaleProductWeightModelDao;
import com.nanyang.tms.dao.saleproduct.SaleProductWeightRuleDao;
import com.nanyang.tms.domain.saleproduct.*;
import com.nanyang.tms.manager.saleproduct.SaleProductManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.HtmlUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Slf4j
@Component("saleProductManager")
public class SaleProductManagerImpl implements SaleProductManager {
    @Autowired
    private SaleProductDao saleProductDao;
    @Autowired
    private SaleProductWeightModelDao saleProductWeightModelDao;
    @Autowired
    private SaleProductWeightRuleDao saleProductWeightRuleDao;
    @Autowired
    private SaleProductCarryRuleDao saleProductCarryRuleDao;
    @Autowired
    private GlobalIdGeneratorUtil globalIdGeneratorUtil;
    @Override
    public PageBean<SaleProductVO> listSaleProduct(SaleProductQuery query) {
      try {
            if (query == null) {
                log.error(TmsCommonEnum.PARAM_IS_NULL.getCode() + TmsCommonEnum.PARAM_IS_NULL.getMessage());
                throw new TmsManagerException(TmsCommonEnum.PARAM_IS_NULL.getCode() ,TmsCommonEnum.PARAM_IS_NULL.getMessage());
            }
            Integer count = saleProductDao.countSaleProduct(query);
            PageBean<SaleProductVO> page = new PageTableBean<SaleProductVO>(query.getPageIndex(), query.getPageSize());
            if (null != count && count != 0) {
                page.setTotalItem(count);
                int startRow = page.getStartRow();
                if (startRow > 0) {
                    startRow -= 1;
                }
                query.setStartRow(startRow);
                page.addAll(saleProductDao.listSaleProduct(query));
            }
            return page;
        } catch (Exception e) {
            throw TmsExceptionUtil.wrapException(e);
        }
    }
    @SystemLog(module =SystemLog.Module.SALEPRODUCT,template="saleProductAdd")
    @Override
    @Transactional
    public void saveSaleProduct(SaleProductBaseVO saleProductBaseVO) {
        try{
            SaleProductVO saleProductVO = saleProductBaseVO.getSaleProductVO();
            SaleProductQuery query=new SaleProductQuery();
            query.setSaleProductName(saleProductVO.getSaleProductName());
            if (saleProductDao.queryVerifySaleProductName(query)>0){
                throw new TmsManagerException(TmsExceptionEnum.SALEPRODUCT_IS_EXIST.getCode(),TmsExceptionEnum.SALEPRODUCT_IS_EXIST.getMessage());
            };
            /*******产品基本信息***********/
            SaleProductDO saleProductDO=new SaleProductDO();
            BeanUtils.copyProperties(saleProductVO,saleProductDO);
            String saleProductCode=TmsSerializeConstant.SALEPRODUCT_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.SALEPRODUCT_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
            saleProductDO.setSaleProductCode(saleProductCode);
            saleProductDO.setGmtCreatePin(saleProductBaseVO.getGmtCreatePin());
            saleProductDO.setIp(saleProductBaseVO.getIp());
            saleProductDao.insert(saleProductDO);

            /*******产品进位规则信息***********/
            List<SaleProductCarryRuleVO> saleProductCarryRuleVOList = saleProductBaseVO.getSaleProductCarryRuleVOList();
            saleProductCarryRuleVOList.forEach(saleProductCarryRuleVO ->{
                SaleProductCarryRuleDO saleProductCarryRuleDO=new SaleProductCarryRuleDO();
                BeanUtils.copyProperties(saleProductCarryRuleVO,saleProductCarryRuleDO);
                String carryRuleCode=TmsSerializeConstant.SALEPRODUCT_CARRY_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.SALEPRODUCT_CARRY_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
                saleProductCarryRuleDO.setSaleProductCode(saleProductCode);
                saleProductCarryRuleDO.setCarryRuleCode(carryRuleCode);
                saleProductCarryRuleDO.setGmtCreatePin(saleProductBaseVO.getGmtCreatePin());
                saleProductCarryRuleDO.setIp(saleProductBaseVO.getIp());
                saleProductCarryRuleDao.insert(saleProductCarryRuleDO);
            });
            /*******产品计重模式信息***********/
            SaleProductWeightModelVO saleProductWeightModelVO = saleProductBaseVO.getSaleProductWeightModelVO();
            SaleProductWeightModelDO saleProductWeightModelDO = new SaleProductWeightModelDO();
            BeanUtils.copyProperties(saleProductWeightModelVO,saleProductWeightModelDO);
            String weightModelCode= TmsSerializeConstant.SALEPRODUCT_WEIGHT_MODEL_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.SALEPRODUCT_WEIGHT_MODEL_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
            saleProductWeightModelDO.setSaleProductCode(saleProductCode);
            saleProductWeightModelDO.setWeightModelCode(weightModelCode);
            saleProductWeightModelDO.setGmtCreatePin(saleProductBaseVO.getGmtCreatePin());
            saleProductWeightModelDO.setIp(saleProductBaseVO.getIp());
            saleProductWeightModelDao.insert(saleProductWeightModelDO);
            /*******产品计重模式规则信息***********/
            List<SaleProductWeightRuleVO> saleProductWeightRuleVOList = saleProductWeightModelVO.getSaleProductWeightRuleVOList();
            saleProductWeightRuleVOList.forEach(saleProductWeightRuleVO ->{
                SaleProductWeightRuleDO saleProductWeightRuleDO = new SaleProductWeightRuleDO();
                BeanUtils.copyProperties(saleProductWeightRuleVO,saleProductWeightRuleDO);

                String weightRuleCode=TmsSerializeConstant.SALEPRODUCT_WEIGHT_RULE_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.SALEPRODUCT_WEIGHT_RULE_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
                saleProductWeightRuleDO.setWeightRuleCode(weightRuleCode);
                saleProductWeightRuleDO.setWeightModelCode(weightModelCode);
                saleProductWeightRuleDO.setGmtCreatePin(saleProductBaseVO.getGmtCreatePin());
                saleProductWeightRuleDO.setIp(saleProductBaseVO.getIp());
                saleProductWeightRuleDO.setConditionExpression(HtmlUtils.htmlUnescape(saleProductWeightRuleDO.getConditionExpression()));

                saleProductWeightRuleDao.insert(saleProductWeightRuleDO);
            });
        } catch (TmsManagerException e) {
            throw TmsExceptionUtil.wrapException(e);
        }
    }
    @SystemLog(module =SystemLog.Module.SALEPRODUCT,template="saleProductUpdate")
    @Override
    @Transactional
    public void updateSaleProduct(SaleProductBaseVO saleProductBaseVO) {
        try {
            SaleProductVO saleProductVO = saleProductBaseVO.getSaleProductVO();
            SaleProductQuery query=new SaleProductQuery();
            query.setSaleProductCode(saleProductVO.getSaleProductCode());
            query.setSaleProductName(saleProductVO.getSaleProductName());
            if (saleProductDao.queryVerifySaleProductName(query)>0){
                throw new TmsManagerException(TmsExceptionEnum.SALEPRODUCT_IS_EXIST.getCode(),TmsExceptionEnum.SALEPRODUCT_IS_EXIST.getMessage());
            };
            Date date = new Date();
            SaleProductDO saleProductDO = new SaleProductDO();
            BeanUtils.copyProperties(saleProductVO,saleProductDO);
            saleProductDO.setGmtModified(date);
            saleProductDO.setGmtModifiedPin(saleProductBaseVO.getGmtModifiedPin());
            saleProductDao.update(saleProductDO);


            String saleProductCode=saleProductVO.getSaleProductCode();
            List<SaleProductCarryRuleVO> saleProductCarryRuleVOS = saleProductCarryRuleDao.selectBySaleProductCode(saleProductCode);
            List<SaleProductCarryRuleVO> saleProductCarryRuleVOList = saleProductBaseVO.getSaleProductCarryRuleVOList();
            saleProductCarryRuleVOS.forEach(saleProductCarryRuleVO ->{
                Optional<SaleProductCarryRuleVO> saleProductCarryRuleVOOptional = saleProductCarryRuleVOList.stream().filter(item -> saleProductCarryRuleVO.getCarryRuleCode().equals(item.getCarryRuleCode())).findFirst();
                if(!saleProductCarryRuleVOOptional.isPresent()){//删除不存在的
                    saleProductCarryRuleDao.deleteByPrimaryKey(saleProductCarryRuleVO.getId());
                }
            });
            saleProductCarryRuleVOList.forEach(saleProductCarryRuleVO ->{
                if(Objects.isNull(saleProductCarryRuleVO.getCarryRuleCode())){//编码不存在添加
                    SaleProductCarryRuleDO saleProductCarryRuleDO = new SaleProductCarryRuleDO();
                    BeanUtils.copyProperties(saleProductCarryRuleVO,saleProductCarryRuleDO);

                    String saleCarryRuleCode=TmsSerializeConstant.SALEPRODUCT_CARRY_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.SALEPRODUCT_CARRY_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
                    saleProductCarryRuleDO.setSaleProductCode(saleProductCode);
                    saleProductCarryRuleDO.setCarryRuleCode(saleCarryRuleCode);
                    saleProductCarryRuleDO.setGmtCreatePin(saleProductBaseVO.getGmtModifiedPin());
                    saleProductCarryRuleDO.setIp(saleProductBaseVO.getIp());
                    saleProductCarryRuleDao.insert(saleProductCarryRuleDO);
                }else{//修改
                    SaleProductCarryRuleDO saleProductCarryRuleDO = new SaleProductCarryRuleDO();
                    BeanUtils.copyProperties(saleProductCarryRuleVO,saleProductCarryRuleDO);
                    saleProductCarryRuleDO.setGmtModified(date);
                    saleProductCarryRuleDO.setGmtModifiedPin(saleProductBaseVO.getGmtModifiedPin());
                    saleProductCarryRuleDao.update(saleProductCarryRuleDO);
                }
            });

            SaleProductWeightModelVO saleProductWeightModelVO = saleProductBaseVO.getSaleProductWeightModelVO();
            SaleProductWeightModelDO saleProductWeightModelDO = new SaleProductWeightModelDO();
            BeanUtils.copyProperties(saleProductWeightModelVO,saleProductWeightModelDO);
            saleProductWeightModelDO.setGmtModified(date);
            saleProductWeightModelDO.setGmtModifiedPin(saleProductBaseVO.getGmtModifiedPin());
            saleProductWeightModelDao.update(saleProductWeightModelDO);
            List<SaleProductWeightRuleVO> saleProductWeightRuleVOS = saleProductWeightRuleDao.selectByModelCode(saleProductWeightModelVO.getWeightModelCode());
            List<SaleProductWeightRuleVO> saleProductWeightRuleVOList = saleProductWeightModelVO.getSaleProductWeightRuleVOList();
            saleProductWeightRuleVOS.forEach(saleProductWeightRuleVO ->{
                Optional<SaleProductWeightRuleVO> first = saleProductWeightRuleVOList.stream().filter(item -> saleProductWeightRuleVO.getWeightRuleCode().equals(item.getWeightRuleCode())).findFirst();
                if(!first.isPresent()){//删除不存在的
                    saleProductWeightRuleDao.deleteByPrimaryKey(saleProductWeightRuleVO.getId());
                }
            });
            saleProductWeightRuleVOList.forEach(saleProductWeightRuleVO ->{
                if(Objects.isNull(saleProductWeightRuleVO.getWeightRuleCode())){//编码不存在添加

                    SaleProductWeightRuleDO saleProductWeightRuleDO = new SaleProductWeightRuleDO();
                    BeanUtils.copyProperties(saleProductWeightRuleVO,saleProductWeightRuleDO);

                    String weightRuleCode=TmsSerializeConstant.SALEPRODUCT_WEIGHT_RULE_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.SALEPRODUCT_WEIGHT_RULE_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
                    saleProductWeightRuleDO.setWeightRuleCode(weightRuleCode);
                    saleProductWeightRuleDO.setWeightModelCode(saleProductWeightModelVO.getWeightModelCode());
                    saleProductWeightRuleDO.setGmtCreatePin(saleProductBaseVO.getGmtModifiedPin());
                    saleProductWeightRuleDO.setIp(saleProductBaseVO.getIp());
                    saleProductWeightRuleDO.setConditionExpression(HtmlUtils.htmlUnescape(saleProductWeightRuleDO.getConditionExpression()));

                    saleProductWeightRuleDao.insert(saleProductWeightRuleDO);
                }else{//修改
                    SaleProductWeightRuleDO saleProductWeightRuleDO = new SaleProductWeightRuleDO();
                    BeanUtils.copyProperties(saleProductWeightRuleVO,saleProductWeightRuleDO);
                    saleProductWeightRuleDO.setGmtModified(date);
                    saleProductWeightRuleDO.setGmtModifiedPin(saleProductBaseVO.getGmtModifiedPin());
                    saleProductWeightRuleDO.setConditionExpression(HtmlUtils.htmlUnescape(saleProductWeightRuleDO.getConditionExpression()));

                    saleProductWeightRuleDao.update(saleProductWeightRuleDO);
                }
            });
        } catch (TmsManagerException e) {
            throw TmsExceptionUtil.wrapException(e);
        }
    }

    @Override
    public SaleProductBaseVO selectSaleProductByCode(String salePoductCode) {
        try {
            SaleProductBaseVO saleProductBaseVO=new SaleProductBaseVO();
            SaleProductVO saleProductVO = saleProductDao.selectByCode(salePoductCode);
            if(Objects.isNull(saleProductVO)){
                throw new TmsManagerException(CommonEnum.NO_CONTENT.getCode(),CommonEnum.NO_CONTENT.getMessage());
            }
            saleProductBaseVO.setSaleProductVO(saleProductVO);
            List<SaleProductCarryRuleVO> saleProductCarryRuleVOS = saleProductCarryRuleDao.selectBySaleProductCode(salePoductCode);
            if(CollectionUtil.isEmpty(saleProductCarryRuleVOS)){
                throw new TmsManagerException(CommonEnum.NO_CONTENT.getCode(),CommonEnum.NO_CONTENT.getMessage());
            }
            saleProductBaseVO.setSaleProductCarryRuleVOList(saleProductCarryRuleVOS);
            SaleProductWeightModelVO saleProductWeightModelVO = saleProductWeightModelDao.selectBySaleProductCode(salePoductCode);
            if(ObjectUtil.isEmpty(saleProductWeightModelVO)){
                throw new TmsManagerException(CommonEnum.NO_CONTENT.getCode(),CommonEnum.NO_CONTENT.getMessage());
            }
            List<SaleProductWeightRuleVO> saleProductWeightRuleVOS = saleProductWeightRuleDao.selectByModelCode(saleProductWeightModelVO.getWeightModelCode());
            if(CollectionUtil.isEmpty(saleProductWeightRuleVOS)){
                throw new TmsManagerException(CommonEnum.NO_CONTENT.getCode(),CommonEnum.NO_CONTENT.getMessage());
            }
            saleProductWeightModelVO.setSaleProductWeightRuleVOList(saleProductWeightRuleVOS);
            saleProductBaseVO.setSaleProductWeightModelVO(saleProductWeightModelVO);
            return saleProductBaseVO;
        } catch (TmsManagerException e) {
            throw TmsExceptionUtil.wrapException(e);
        }
    }
}
